home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 16 / CU Amiga Magazine's Super CD-ROM 16 (1997-10-16)(EMAP Images)(GB)[!][issue 1997-11].iso / CUCD / Graphics / Ghostscript / source / gsimage.c < prev    next >
C/C++ Source or Header  |  1997-05-06  |  9KB  |  312 lines

  1. /* Copyright (C) 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gsimage.c */
  20. /* Image setup procedures for Ghostscript library */
  21. #include "memory_.h"
  22. #include "gx.h"
  23. #include "gserrors.h"
  24. #include "gsstruct.h"
  25. #include "gscspace.h"
  26. #include "gsmatrix.h"        /* for gsiparam.h */
  27. #include "gsimage.h"
  28. #include "gxarith.h"        /* for igcd */
  29. #include "gxdevice.h"
  30. #include "gzstate.h"
  31.  
  32. /* Define the maximum number of image components. */
  33. #ifdef DPNEXT
  34. #  define max_components 5
  35. #else
  36. #  define max_components 4
  37. #endif
  38.  
  39. /* Define the enumeration state for this interface layer. */
  40. /*typedef struct gs_image_enum_s gs_image_enum;*/    /* in gsimage.h */
  41. struct gs_image_enum_s {
  42.         /* The following are set at initialization time. */
  43.     gs_memory_t *memory;
  44.     gx_device *dev;
  45.     bool skip;        /* if true, just skip over the data */
  46.     void *info;        /* driver bookkeeping structure */
  47.     int num_components;
  48.     bool multi;
  49.     int num_planes;
  50.     int width, height;
  51.     int bpp;        /* bits per pixel (per plane, if multi) */
  52.     uint raster;        /* bytes per row (per plane), no padding */
  53.         /* The following are updated dynamically. */
  54.     int plane_index;    /* index of next plane of data */
  55.     int y;
  56.     uint pos;        /* byte position within the scan line */
  57.     gs_const_string sources[max_components];    /* source data */
  58.     gs_string rows[max_components];        /* row buffers */
  59.     bool error;
  60. };
  61. gs_private_st_composite(st_gs_image_enum, gs_image_enum, "gs_image_enum",
  62.   gs_image_enum_enum_ptrs, gs_image_enum_reloc_ptrs);
  63. #define gs_image_enum_num_ptrs 2
  64.  
  65. /* GC procedures */
  66. #define eptr ((gs_image_enum *)vptr)
  67. private ENUM_PTRS_BEGIN(gs_image_enum_enum_ptrs) {
  68.     /* Enumerate the data planes. */
  69.     index -= gs_image_enum_num_ptrs;
  70.     if ( index < eptr->plane_index )
  71.       { *pep = (void *)&eptr->sources[index];
  72.         return ptr_string_type;
  73.       }
  74.     index -= eptr->plane_index;
  75.     if ( index < eptr->num_planes )
  76.       { *pep = (void *)&eptr->rows[index];
  77.         return ptr_string_type;
  78.       }
  79.     return 0;
  80.     }
  81.     ENUM_PTR(0, gs_image_enum, dev);
  82.     ENUM_PTR(1, gs_image_enum, info);
  83. ENUM_PTRS_END
  84. private RELOC_PTRS_BEGIN(gs_image_enum_reloc_ptrs) {
  85.     int i;
  86.     RELOC_PTR(gs_image_enum, dev);
  87.     RELOC_PTR(gs_image_enum, info);
  88.     for ( i = 0; i < eptr->plane_index; i++ )
  89.       RELOC_CONST_STRING_PTR(gs_image_enum, sources[i]);
  90.     for ( i = 0; i < eptr->num_planes; i++ )
  91.       RELOC_STRING_PTR(gs_image_enum, rows[i]);
  92. } RELOC_PTRS_END
  93. #undef eptr
  94.  
  95. /* Allocate an image enumerator. */
  96. private void
  97. image_enum_init(gs_image_enum *pie)
  98. {    /* Clean pointers for GC. */
  99.     int i;
  100.     pie->info = 0;
  101.     pie->dev = 0;
  102.     for ( i = 0; i < countof(pie->sources); ++i )
  103.       { pie->sources[i].data = 0, pie->sources[i].size = 0;
  104.         pie->rows[i].data = 0, pie->rows[i].size = 0;
  105.       }
  106. }
  107. gs_image_enum *
  108. gs_image_enum_alloc(gs_memory_t *mem, client_name_t cname)
  109. {    gs_image_enum *pie =
  110.       gs_alloc_struct(mem, gs_image_enum, &st_gs_image_enum, cname);
  111.  
  112.     if ( pie != 0 )
  113.       { pie->memory = mem;
  114.         image_enum_init(pie);
  115.       }
  116.     return pie;
  117. }
  118.  
  119. /* Start processing an image. */
  120. int
  121. gs_image_init(gs_image_enum *pie, const gs_image_t *pim, bool multi,
  122.   gs_state *pgs)
  123. {    gx_device *dev = gs_currentdevice_inline(pgs);
  124.     gs_image_t image;
  125.     ulong samples_per_row = pim->Width;
  126.     int code;
  127.  
  128.     if ( pim->Width == 0 || pim->Height == 0 )
  129.       return 1;
  130.     image = *pim;
  131.     image_enum_init(pie);
  132.     pie->skip = pgs->in_charpath;
  133.     if ( image.ImageMask )
  134.       { image.ColorSpace = NULL;
  135.         if ( pgs->in_cachedevice <= 1 )
  136.           image.adjust = false;
  137.         pie->num_components = pie->num_planes = 1;
  138.       }
  139.     else
  140.       { if ( pgs->in_cachedevice )
  141.           return_error(gs_error_undefined);
  142.         if ( image.ColorSpace == NULL )
  143.           image.ColorSpace = gs_color_space_DeviceGray();
  144.         pie->num_components =
  145.           gs_color_space_num_components(image.ColorSpace);
  146. #ifdef DPNEXT
  147.         if ( pim->HasAlpha )
  148.           pie->num_components++;
  149. #endif
  150.         if ( multi )
  151.           pie->num_planes = pie->num_components;
  152.         else
  153.           { pie->num_planes = 1;
  154.         samples_per_row *= pie->num_components;
  155.           }
  156.       }
  157.     if ( image.ImageMask | image.CombineWithColor )
  158.       gx_set_dev_color(pgs);
  159.     if ( !pie->skip )
  160.       { code = (*dev_proc(dev, begin_image))
  161.           (dev, (const gs_imager_state *)pgs, &image,
  162.            (multi ? gs_image_format_component_planar : gs_image_format_chunky),
  163.            NULL, pgs->dev_color, pgs->clip_path, pie->memory, &pie->info);
  164.         if ( code < 0 )
  165.           return code;
  166.       }
  167.     pie->dev = dev;
  168.     pie->multi = multi;
  169.     pie->bpp =
  170.       image.BitsPerComponent * pie->num_components / pie->num_planes;
  171.     pie->width = image.Width;
  172.     pie->height = image.Height;
  173.     pie->raster = (samples_per_row * image.BitsPerComponent + 7) >> 3;
  174.     /* Initialize the dynamic part of the state. */
  175.     pie->plane_index = 0;
  176.     pie->y = 0;
  177.     pie->pos = 0;
  178.     pie->error = false;
  179.     return 0;
  180. }
  181.  
  182. /*
  183.  * Return the number of bytes of data per row
  184.  * (per plane, if MultipleDataSources is true).
  185.  */
  186. uint
  187. gs_image_bytes_per_row(const gs_image_enum *pie)
  188. {    return pie->raster;
  189. }
  190.  
  191. /* Process the next piece of an image. */
  192. private int
  193. copy_planes(gx_device *dev, gs_image_enum *pie, const byte **planes, int h)
  194. {    int code =
  195.       (pie->skip ? (pie->y + h < pie->height ? 0 : 1) : 
  196.        (*dev_proc(dev, image_data))(dev, pie->info, planes, 0,
  197.                     pie->raster, h));
  198.  
  199.     if ( code < 0 )
  200.       pie->error = true;
  201.     return code;
  202. }
  203. int
  204. gs_image_next(gs_image_enum *pie, const byte *dbytes, uint dsize,
  205.   uint *pused)
  206. {    gx_device *dev;
  207.     uint left;
  208.     int num_planes;
  209.     uint raster;
  210.     uint pos;
  211.     int code;
  212.  
  213.     /*
  214.      * Handle the following differences between gs_image_next and
  215.      * the device image_data procedure:
  216.      *
  217.      *    - image_data requires an array of planes; gs_image_next
  218.      *    expects planes in successive calls.
  219.      *
  220.      *    - image_data requires that each call pass entire rows;
  221.      *    gs_image_next allows arbitrary amounts of data.
  222.      */
  223.     if ( pie->plane_index != 0 )
  224.       if ( dsize != pie->sources[0].size )
  225.         return_error(gs_error_rangecheck);
  226.     pie->sources[pie->plane_index].data = dbytes;
  227.     pie->sources[pie->plane_index].size = dsize;
  228.     if ( ++(pie->plane_index) != pie->num_planes )
  229.       return 0;
  230.     /* We have a full set of planes. */
  231.     dev = pie->dev;
  232.     left = dsize;
  233.     num_planes = pie->num_planes;
  234.     raster = pie->raster;
  235.     pos = pie->pos;
  236.     code = 0;
  237.     while ( left && pie->y < pie->height )
  238.       { const byte *planes[max_components];
  239.         int i;
  240.  
  241.         for ( i = 0; i < num_planes; ++i )
  242.           planes[i] = pie->sources[i].data + dsize - left;
  243.         if ( pos == 0 && left >= raster )
  244.           { /* Pass (a) row(s) directly from the source. */
  245.         int h = left / raster;
  246.         if ( h > pie->height - pie->y )
  247.           h = pie->height - pie->y;
  248.         code = copy_planes(dev, pie, planes, h);
  249.         if ( code < 0 )
  250.           break;
  251.         left -= raster * h;
  252.         pie->y += h;
  253.           }
  254.         else
  255.           { /* Buffer a partial row. */
  256.         uint count = min(left, raster - pos);
  257.         if ( pie->rows[0].data == 0 )
  258.           { /* Allocate the row buffers. */
  259.             for ( i = 0; i < num_planes; ++i )
  260.               { byte *row = gs_alloc_string(pie->memory, raster,
  261.                             "gs_image_next(row)");
  262.                 if ( row == 0 )
  263.               { code = gs_note_error(gs_error_VMerror);
  264.                 while ( --i >= 0 )
  265.                   { gs_free_string(pie->memory, pie->rows[i].data,
  266.                            raster, "gs_image_next(row)");
  267.                     pie->rows[i].data = 0;
  268.                 pie->rows[i].size = 0;
  269.                   }
  270.                 break;
  271.               }
  272.             pie->rows[i].data = row;
  273.             pie->rows[i].size = raster;
  274.               }
  275.             if ( code < 0 )
  276.               break;
  277.           }
  278.         for ( i = 0; i < num_planes; ++i )
  279.           memcpy(pie->rows[i].data + pos, planes[i], count);
  280.         pos += count;
  281.         left -= count;
  282.         if ( pos == raster )
  283.           { for ( i = 0; i < num_planes; ++i )
  284.               planes[i] = pie->rows[i].data;
  285.             code = copy_planes(dev, pie, planes, 1);
  286.             if ( code < 0 )
  287.               break;
  288.             pos = 0;
  289.             pie->y++;
  290.           }
  291.           }
  292.       }
  293.     pie->pos = pos;
  294.     pie->plane_index = 0;
  295.     *pused = dsize - left;
  296.     return code;
  297. }
  298.  
  299. /* Clean up after processing an image. */
  300. void
  301. gs_image_cleanup(gs_image_enum *pie)
  302. {    gx_device *dev = pie->dev;
  303.     int i;
  304.  
  305.     for ( i = 0; i < pie->num_planes; ++i )
  306.       gs_free_string(pie->memory, pie->rows[i].data,
  307.              pie->rows[i].size, "gs_image_cleanup(row)");
  308.     if ( !pie->skip )
  309.       (*dev_proc(dev, end_image))(dev, pie->info, !pie->error);
  310.     /* Don't free the local enumerator -- the client does that. */
  311. }
  312.